package netty.session;

import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;

import java.util.Collection;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * 基于内存的Netty Session存储
 * @param <K> Session Key类型
 * @param <S> Session数据类型
 */
public class NettySessionStore<K, S> {
    private Cache<K, S> sessionCache;
    private NettySessionStoreListener<K, S> listener;

    /**
     *
     * @param expireTime 超时时间，单位秒。在指定的时间没有读取或更新的Session Key将移除
     * @param listener
     */
    @SuppressWarnings("unchecked")
    public NettySessionStore(long expireTime, NettySessionStoreListener<K, S> listener) {
        Caffeine<Object, Object> caffeine = Caffeine.newBuilder().expireAfterAccess(expireTime, TimeUnit.SECONDS);
        if (listener != null) {
            this.listener = listener;
            caffeine.removalListener((key, value, cause) -> listener.removed((K) key, (S) value));
        }
        sessionCache = caffeine.build();
    }


    public void put(K key, S session) {
        sessionCache.put(key, session);
        if (listener != null) {
            listener.added(key, session);
        }
    }

    public S get(K key) {
        return sessionCache.getIfPresent(key);
    }

    public void remove(K key) {
        sessionCache.invalidate(key);
    }

    public long size() {
        return sessionCache.estimatedSize();
    }

    public Set<K> keys() {
        return sessionCache.asMap().keySet();
    }

    public Collection<S> sessions() {
        return sessionCache.asMap().values();
    }

}
